knitr::opts_chunk$set(echo = TRUE)
library(kableExtra)
library(mice) #IMP
## 
## Attaching package: 'mice'
## The following object is masked from 'package:stats':
## 
##     filter
## The following objects are masked from 'package:base':
## 
##     cbind, rbind
library(knitr)
library(FactoMineR)
library(factoextra)
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(corrplot)
## corrplot 0.92 loaded
library(arules) #discretize
## Loading required package: Matrix
## 
## Attaching package: 'arules'
## The following objects are masked from 'package:base':
## 
##     abbreviate, write
library(clValid)
## Loading required package: cluster
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:arules':
## 
##     intersect, recode, setdiff, setequal, union
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(readr)
library(Rtsne)
library(clustMixType)
library(fpc)
library(arulesViz)
library(dplyr)
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v tibble  3.1.6     v stringr 1.4.0
## v tidyr   1.2.0     v forcats 0.5.1
## v purrr   0.3.4
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x tidyr::expand()     masks Matrix::expand()
## x dplyr::filter()     masks mice::filter(), stats::filter()
## x dplyr::group_rows() masks kableExtra::group_rows()
## x dplyr::lag()        masks stats::lag()
## x tidyr::pack()       masks Matrix::pack()
## x dplyr::recode()     masks arules::recode()
## x tidyr::unpack()     masks Matrix::unpack()
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
data = read.csv("C:\\Users\\EvaCantin\\Desktop\\UNI\\SEGUNDO\\PROYECTO\\Clustering\\vendImp.csv", sep=';', as.is = FALSE, row.names = 1)
datosA= read.csv("C:\\Users\\EvaCantin\\Desktop\\UNI\\SEGUNDO\\PROYECTO\\Clustering\\venta_pisos.csv", sep=';', as.is = FALSE, row.names = 1)
vend=data

1 ANÁLISIS 1: Reglas de asociación

1.1 Creando el conjunto de transacciones

Las reglas de asociación son un método útil para la búsqueda de patrones dentro un conjunto de transacciones aplicadas a variables categorícas, generalmente binarias. Para ello, a parte de trabajar con las variables binarias que hay en la base de datos, también se realiza una categorización de variables numéricas, con el fin de tener más información de los patrones de los inmuebles.

# Categorizamos los baños, las habitaciones, la variación del precio y los metros cuadrados

data$baños_cat=cut(data$baños, breaks = c(0,1,10),labels=c("1","+1"),include.lowest = TRUE)
data$hab_cat=cut(data$habitaciones, breaks = c(0,3,10),labels=c("1-3","+3"), include.lowest = TRUE)
data$var_precio=cut(data$variacion_precio,
                    breaks = c(-999999,-0.001,0.001,999999),
                    labels=c("baja",'igual',"sube"),
                    include.lowest = TRUE)
data$m2_cat=cut(data$variacion_precio, breaks = c(0,70,86,99,118,148,750),include.lowest = TRUE)

# Creamos un data frame con las variables elegidas
sub_data=cbind(data[,4:7],a_reformar=data[,9],distrito=data[,15],data[,17:23],vistas=data[,25],data[,30:32])
data1<-data.frame(lapply(sub_data,factor))
data1=cbind(data1,planta_cat=data$planta_cat,tipo_vendedor=as.factor(data$tipo_vendedor))

# Para poder trabajar con la librería Arules convertimos el data frame a trasacción
data2 <- as(data1, "transactions")

1.2 Búsqueda de los items e itemsets más frecuentes

freq_items=itemFrequency(x = data2, type = "absolute")
kable(freq_items %>% sort(decreasing = TRUE) %>% head(20))
x
a_reformar=2 2100
tipo_vendedor=2 2100
piscina=0 2073
vistas=0 2073
var_precio=igual 2073
m2_cat=[0,70] 2073
trastero=0 1903
garaje.incluido=0 1766
acceso.adaptado=0 1698
ascensor=1 1685
terraza=0 1586
hab_cat=1-3 1556
balcon=0 1282
calefaccion=1 1218
aire.acondicionado=1 1183
aire.acondicionado=0 1038
calefaccion=0 1003
habitaciones=3 956
balcon=1 939
planta_cat=Baja 856
# Se utiliza un soporte alto porque se busca las características más frecuentes
itemsets=apriori(data2,parameter = list(support = 0.1, target = "frequent itemset", minlen=2))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##          NA    0.1    1 none FALSE            TRUE       5     0.1      2
##  maxlen            target  ext
##      10 frequent itemsets TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 222 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[211 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [35 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(support = 0.1, target = "frequent
## itemset", : Mining stopped (maxlen reached). Only patterns up to a length of 10
## returned!
##  done [0.30s].
## sorting transactions ... done [0.00s].
## writing ... [124276 set(s)] done [0.02s].
## creating S4 object  ... done [0.05s].
top_15_itemsets=sort(itemsets, by = "support", decreasing = TRUE)[1:15]
kable(inspect(top_15_itemsets))
##      items                                       support   count
## [1]  {a_reformar=2, tipo_vendedor=2}             0.9455200 2100 
## [2]  {vistas=0, var_precio=igual}                0.9333633 2073 
## [3]  {vistas=0, m2_cat=[0,70]}                   0.9333633 2073 
## [4]  {var_precio=igual, m2_cat=[0,70]}           0.9333633 2073 
## [5]  {vistas=0, var_precio=igual, m2_cat=[0,70]} 0.9333633 2073 
## [6]  {piscina=0, a_reformar=2}                   0.8851869 1966 
## [7]  {piscina=0, tipo_vendedor=2}                0.8851869 1966 
## [8]  {piscina=0, a_reformar=2, tipo_vendedor=2}  0.8851869 1966 
## [9]  {a_reformar=2, vistas=0}                    0.8824854 1960 
## [10] {vistas=0, tipo_vendedor=2}                 0.8824854 1960 
## [11] {a_reformar=2, var_precio=igual}            0.8824854 1960 
## [12] {var_precio=igual, tipo_vendedor=2}         0.8824854 1960 
## [13] {a_reformar=2, m2_cat=[0,70]}               0.8824854 1960 
## [14] {m2_cat=[0,70], tipo_vendedor=2}            0.8824854 1960 
## [15] {a_reformar=2, vistas=0, var_precio=igual}  0.8824854 1960
items support count
[1] {a_reformar=2, tipo_vendedor=2} 0.9455200 2100
[2] {vistas=0, var_precio=igual} 0.9333633 2073
[3] {vistas=0, m2_cat=[0,70]} 0.9333633 2073
[4] {var_precio=igual, m2_cat=[0,70]} 0.9333633 2073
[5] {vistas=0, var_precio=igual, m2_cat=[0,70]} 0.9333633 2073
[6] {piscina=0, a_reformar=2} 0.8851869 1966
[7] {piscina=0, tipo_vendedor=2} 0.8851869 1966
[8] {piscina=0, a_reformar=2, tipo_vendedor=2} 0.8851869 1966
[9] {a_reformar=2, vistas=0} 0.8824854 1960
[10] {vistas=0, tipo_vendedor=2} 0.8824854 1960
[11] {a_reformar=2, var_precio=igual} 0.8824854 1960
[12] {var_precio=igual, tipo_vendedor=2} 0.8824854 1960
[13] {a_reformar=2, m2_cat=[0,70]} 0.8824854 1960
[14] {m2_cat=[0,70], tipo_vendedor=2} 0.8824854 1960
[15] {a_reformar=2, vistas=0, var_precio=igual} 0.8824854 1960

1.3 Tipos de algoritmos (Apriori y Eclat)

reglas_a=apriori(data2, parameter = list(supp = 0.05))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.8    0.1    1 none FALSE            TRUE       5    0.05      1
##  maxlen target  ext
##      10  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 111 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[211 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [43 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(supp = 0.05)): Mining stopped (maxlen
## reached). Only patterns up to a length of 10 returned!
##  done [0.84s].
## writing ... [2039806 rule(s)] done [0.38s].
## creating S4 object  ... done [1.54s].
# Filtramos las más relevantes
filtro_a <- interestMeasure(reglas_a, 
                              measure = "lift",
                              transactions = data2)
summary(filtro_a)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.8571  1.0352  1.0714  1.1338  1.0883 18.3554
# Se utiliza el mismo soporte para su comparación
reglas_e=eclat(data2, parameter = list(supp = 0.05))
## Eclat
## 
## parameter specification:
##  tidLists support minlen maxlen            target  ext
##     FALSE    0.05      1     10 frequent itemsets TRUE
## 
## algorithmic control:
##  sparse sort verbose
##       7   -2    TRUE
## 
## Absolute minimum support count: 111 
## 
## create itemset ... 
## set transactions ...[211 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [43 item(s)] done [0.00s].
## creating bit matrix ... [43 row(s), 2221 column(s)] done [0.00s].
## writing  ... [462149 set(s)] done [0.08s].
## Creating S4 object  ... done [0.16s].
filtro_e <- interestMeasure(reglas_e, 
                              measure = "lift",
                              transactions = data2)
summary(filtro_e)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.4972  1.0409  1.2684  1.6526  1.7721 21.0816

El algoritmo apriori realiza menor dispersión en los datos, lo que demuestra un mejor desempeño para este caso.

1.4 Eligiendo el soporte

Para aquellas reglas que se cumplen en la mayor parte de los inmuebles, se utiliza un soporte alto. Tras varias pruebas, un soporte alto que posea un lift significativo, es decir, mayor o igual a 2, es de 0,1.

reglas1 = apriori(data2, parameter = list(supp = 0.1, conf = 0.8))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.8    0.1    1 none FALSE            TRUE       5     0.1      1
##  maxlen target  ext
##      10  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 222 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[211 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [35 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(supp = 0.1, conf = 0.8)): Mining
## stopped (maxlen reached). Only patterns up to a length of 10 returned!
##  done [0.32s].
## writing ... [537372 rule(s)] done [0.10s].
## creating S4 object  ... done [0.20s].

Por el contrario, si se desea buscar casos más concretos, entonces se baja el soporte.

reglas2 = apriori(data2, parameter = list(supp = 0.025, conf = 0.8))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.8    0.1    1 none FALSE            TRUE       5   0.025      1
##  maxlen target  ext
##      10  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 55 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[211 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [54 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(supp = 0.025, conf = 0.8)): Mining
## stopped (maxlen reached). Only patterns up to a length of 10 returned!
##  done [2.64s].
## writing ... [6168929 rule(s)] done [1.67s].
## creating S4 object  ... done [3.67s].

1.5 Reducción de reglas

Para trabajar con un número más reducido de reglas, se ha descartado reglas redundantes, ya que cubre la misma cantidad información o menor que otra regla de la misma utilidad y relevancia.

nr1 = reglas1[!is.redundant(x =reglas1, measure = "confidence")]
nr1.sorted = arules::sort(nr1, by="lift", decreasing=T)
nr2 = reglas2[!is.redundant(x =reglas2, measure = "confidence")]
nr2.sorted = arules::sort(nr2, by="lift", decreasing=T)

1.6 Medidas de calidad

El Test Exacto de Fisher es una medida de calidad utilizada para estudiar la posible asociación entre dos variables cualitativas.

fisher = interestMeasure(nr1.sorted, measure = c("fishersExactTest"),transactions = data2)
quality(nr1.sorted) = cbind(quality(nr1.sorted), fisher)
df1=as(nr1.sorted, Class = "data.frame")
kable(df1[1:8,])
rules support confidence coverage lift count fisher
6276 {balcon=1,trastero=0,hab_cat=+3} => {habitaciones=4} 0.1067087 0.8374558 0.1274201 3.734919 237 0
26384 {terraza=0,acceso.adaptado=0,trastero=0,hab_cat=+3} => {habitaciones=4} 0.1049077 0.8291815 0.1265196 3.698016 233 0
78577 {piscina=0,terraza=0,trastero=0,vistas=0,hab_cat=+3} => {habitaciones=4} 0.1283206 0.8142857 0.1575867 3.631584 285 0
78582 {piscina=0,terraza=0,trastero=0,hab_cat=+3,var_precio=igual} => {habitaciones=4} 0.1283206 0.8142857 0.1575867 3.631584 285 0
78587 {piscina=0,terraza=0,trastero=0,hab_cat=+3,m2_cat=[0,70]} => {habitaciones=4} 0.1283206 0.8142857 0.1575867 3.631584 285 0
26422 {piscina=0,terraza=0,trastero=0,hab_cat=+3} => {habitaciones=4} 0.1359748 0.8140162 0.1670419 3.630381 302 0
26426 {terraza=0,trastero=0,vistas=0,hab_cat=+3} => {habitaciones=4} 0.1296713 0.8135593 0.1593877 3.628344 288 0
26430 {terraza=0,trastero=0,hab_cat=+3,var_precio=igual} => {habitaciones=4} 0.1296713 0.8135593 0.1593877 3.628344 288 0
fisher <- interestMeasure(nr2.sorted, measure = c("fishersExactTest"),transactions = data2)
quality(nr2.sorted) <- cbind(quality(nr2.sorted), fisher)
df2=as(nr2.sorted, Class = "data.frame")
kable(df2[1:20,])
rules support confidence coverage lift count fisher
101 {a_reformar=1} => {tipo_vendedor=1} 0.0544800 1.0000000 0.0544800 18.355372 121 0
102 {tipo_vendedor=1} => {a_reformar=1} 0.0544800 1.0000000 0.0544800 18.355372 121 0
66882 {ascensor=0,terraza=0,vistas=0,planta_cat=Alta} => {planta=5} 0.0310671 0.8313253 0.0373706 7.725412 69 0
66886 {ascensor=0,terraza=0,var_precio=igual,planta_cat=Alta} => {planta=5} 0.0310671 0.8313253 0.0373706 7.725412 69 0
66890 {ascensor=0,terraza=0,m2_cat=[0,70],planta_cat=Alta} => {planta=5} 0.0310671 0.8313253 0.0373706 7.725412 69 0
66846 {ascensor=0,vistas=0,hab_cat=1-3,planta_cat=Alta} => {planta=5} 0.0288158 0.8311688 0.0346691 7.723958 64 0
66850 {ascensor=0,hab_cat=1-3,var_precio=igual,planta_cat=Alta} => {planta=5} 0.0288158 0.8311688 0.0346691 7.723958 64 0
66854 {ascensor=0,hab_cat=1-3,m2_cat=[0,70],planta_cat=Alta} => {planta=5} 0.0288158 0.8311688 0.0346691 7.723958 64 0
13632 {ascensor=0,terraza=0,planta_cat=Alta} => {planta=5} 0.0319676 0.8255814 0.0387213 7.672035 71 0
13647 {ascensor=0,vistas=0,planta_cat=Alta} => {planta=5} 0.0337686 0.8241758 0.0409725 7.658973 75 0
13650 {ascensor=0,var_precio=igual,planta_cat=Alta} => {planta=5} 0.0337686 0.8241758 0.0409725 7.658973 75 0
13653 {ascensor=0,m2_cat=[0,70],planta_cat=Alta} => {planta=5} 0.0337686 0.8241758 0.0409725 7.658973 75 0
13629 {ascensor=0,hab_cat=1-3,planta_cat=Alta} => {planta=5} 0.0297163 0.8148148 0.0364701 7.571982 66 0
2041 {ascensor=0,planta_cat=Alta} => {planta=5} 0.0346691 0.8105263 0.0427735 7.532129 77 0
2020514 {ascensor=1,piscina=0,terraza=0,a_reformar=2,acceso.adaptado=0,hab_cat=+3,planta_cat=Baja} => {planta=2} 0.0252139 0.8615385 0.0292661 5.157620 56 0
2020519 {ascensor=1,piscina=0,terraza=0,acceso.adaptado=0,hab_cat=+3,planta_cat=Baja,tipo_vendedor=2} => {planta=2} 0.0252139 0.8615385 0.0292661 5.157620 56 0
923431 {ascensor=1,piscina=0,terraza=0,acceso.adaptado=0,hab_cat=+3,planta_cat=Baja} => {planta=2} 0.0261144 0.8529412 0.0306168 5.106152 58 0
923435 {ascensor=1,terraza=0,a_reformar=2,acceso.adaptado=0,hab_cat=+3,planta_cat=Baja} => {planta=2} 0.0252139 0.8358209 0.0301666 5.003661 56 0
923439 {ascensor=1,terraza=0,acceso.adaptado=0,hab_cat=+3,planta_cat=Baja,tipo_vendedor=2} => {planta=2} 0.0252139 0.8358209 0.0301666 5.003661 56 0
923493 {ascensor=1,terraza=0,a_reformar=2,trastero=0,hab_cat=+3,planta_cat=Baja} => {planta=2} 0.0288158 0.8311688 0.0346691 4.975811 64 0

1.7 Representación gráfica de las reglas

plot(nr1.sorted[1:100], method="paracoord", control=list(reorder=TRUE))

plot(nr2.sorted[1:100], method="paracoord", control=list(reorder=TRUE))

1.8 Eligiendo consecuente

A continuación, se realiza, para este nuevo dataset, como los apartados anteriores. Ahora, se añade como consecuente la variable binaria que indica si el piso está vendido o no. Con la fianlidad de conocer que carácteristicas poseen las propiedades para que tengan mayor probabiblidad de ser vendidas. Y, por el contrario, observar cuáles son las que no se produzca la venta.

sum_ven=datosA%>%
  group_by(vendido)%>%
  summarize(support=n()/nrow(data1),support_count=n())
#Graficar
ggplot(data=sum_ven,aes(x=vendido,y=support, fill=vendido))+
  geom_bar(stat='identity')+
  coord_flip()+
  theme_minimal()

# Categorizamos las variables
datosA$baños_cat=cut(datosA$ad_characteristics_bathNumber,breaks = c(0,1,10),labels=c("1","+1"),include.lowest = TRUE)
datosA$hab_cat=cut(datosA$ad_characteristics_roomNumber, breaks = c(0,3,10),labels=c("1-3","+3"),include.lowest = TRUE)
datosA$planta_cat=cut(datosA$planta, breaks = c(0, 2, 4,100),labels=c("Baja", "Media", "Alta"),include.lowest = TRUE)
datosA$var_precio=cut(datosA$variacion_precio,
                    breaks = c(-999999,-0.001,0.001,999999),
                    labels=c("baja",'igual',"sube"),
                    include.lowest = TRUE)
sub_datos1<-select(datosA,ad_characteristics_hasGarden,ad_characteristics_hasLift,ad_characteristics_hasParking,
                   ad_characteristics_hasSwimmingPool,ad_characteristics_hasTerrace,ad_condition_isGoodCondition,
                   ad_condition_isNeedsRenovating,ad_owner_type,distrito,planta_cat,vistas,vendido,baños_cat,
                   hab_cat,var_precio)

datosA1<-data.frame(lapply(sub_datos1,factor))
colnames(datosA1)<-c('jardin','ascensor','parking','piscina','terraza','buena_condicion','a_reformar','tipo_vendedor',
                     'distrito','planta_cat','vistas','vendido','baños_cat','hab_cat','var_precio')
datosA1 <- as(datosA1, "transactions")
reglasA = apriori(datosA1, parameter = list(supp = 0.003, conf = 0.8),
                appearance = list(rhs=c("vendido=1"))) 
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.8    0.1    1 none FALSE            TRUE       5   0.003      1
##  maxlen target  ext
##      10  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 19 
## 
## set item appearances ...[1 item(s)] done [0.00s].
## set transactions ...[50 item(s), 6520 transaction(s)] done [0.01s].
## sorting and recoding items ... [50 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(datosA1, parameter = list(supp = 0.003, conf = 0.8), : Mining
## stopped (maxlen reached). Only patterns up to a length of 10 returned!
##  done [1.30s].
## writing ... [12 rule(s)] done [0.06s].
## creating S4 object  ... done [0.03s].
nra = reglasA[!is.redundant(x =reglasA, measure = "confidence")]
nra.sorted = arules::sort(nra, by="lift", decreasing=T)
fisher = interestMeasure(nra, measure = c("fishersExactTest"),transactions = datosA1)
quality(nra.sorted) = cbind(quality(nra.sorted), fisher)
dfA=as(nra.sorted, Class = "data.frame")
# Eliminamos p-valor >=0.05
dfA<-dfA[which(dfA$fisher<0.05),]
kable(dfA[1:4,])
rules support confidence coverage lift count fisher
8 {buena_condicion=0,tipo_vendedor=2,distrito=la saïdia,hab_cat=1-3,var_precio=igual} => {vendido=1} 0.0035276 0.8518519 0.0041411 2.310347 23 7.00e-07
1 {ascensor=1,buena_condicion=0,distrito=la saïdia,hab_cat=1-3} => {vendido=1} 0.0033742 0.8461538 0.0039877 2.294893 22 1.10e-06
5 {parking=0,distrito=quatre carreres,planta_cat=Media,baños_cat=1} => {vendido=1} 0.0030675 0.8333333 0.0036810 2.260122 20 1.10e-06
2 {buena_condicion=0,distrito=la saïdia,hab_cat=1-3,var_precio=igual} => {vendido=1} 0.0035276 0.8214286 0.0042945 2.227835 23 1.28e-05

2 ANÁLISIS 2: CLUSTERING

borrar = c("latitud", "longitud", "url", "distrito", "barrio", "variacion_precio", "dias_venta", "planta_cat", "preciom2", "m2", "precio_final")

dataCluster = vend[ , !(names(vend) %in% borrar)]

descVend2 = data.frame("variable" = colnames(dataCluster),
                      "tipo" = c(rep("numerical", 1), rep("binary", 4), "numerical", rep("binary", 9), "numerical", "binary"))
rownames(descVend2) = descVend2$variable

dataCluster[which(descVend2$tipo == 'binary')] = lapply(dataCluster[which(descVend2$tipo == 'binary')], as.factor)

2.1 Matriz distancia de Gower

Cuando se dispone de un conjunto de datos mixto, es decir, un conjunto de individuos sobre los que se han observado tanto variables cuantitativas como cualitativas (o categóricas), la distancia de Gower es la apropiada.

gower_dist = daisy(dataCluster, metric = "gower", type = list(logratio = 3))
gower_mat = as.matrix(gower_dist)

2.2 Tendencia agrupamiento datos

Para estudiar la tendencia de agrupamiento de los datos, utilizaremos un mapa de calor. Descartamos el uso del estadístico de Hopkins porque está programado para la distancia euclídea y no para la de Gower. Como se puede ver en el mapa de calor, a simple vista, parece haber 6 u 8 clusters.

2.3 Métodos jerárquicos: WARD, Media, Centroide y Mediana

En primer lugar, los métodos que se van a utilizar son jerárquicos: Ward, Media, Centroide y Mediana. La elección de los métodos no es aleatoria, sino que los tres primeros se han escogido por ser los más comunes y el de la Mediana, por ser un estadístico robusto (en comparación con la media)

cstats.table <- function(dist, tree, k) {
clust.assess <- c("cluster.number","n","within.cluster.ss","average.within","average.between","wb.ratio","dunn2","avg.silwidth")
clust.size <- c("cluster.size")
stats.names <- c()
row.clust <- c()
output.stats <- matrix(ncol = k, nrow = length(clust.assess))
cluster.sizes <- matrix(ncol = k, nrow = k)
for(i in c(1:k)){
  row.clust[i] <- paste("Cluster-", i, " size")
}

for(i in c(2:k)){
  stats.names[i] <- paste("Test", i-1)
  
  for(j in seq_along(clust.assess)){
    output.stats[j, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.assess])[j]
    
  }
  
  for(d in 1:k) {
    cluster.sizes[d, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.size])[d]
    dim(cluster.sizes[d, i]) <- c(length(cluster.sizes[i]), 1)
    cluster.sizes[d, i]
  }
}

output.stats.df <- data.frame(output.stats)
cluster.sizes <- data.frame(cluster.sizes)
cluster.sizes[is.na(cluster.sizes)] <- 0
rows.all <- c(clust.assess, row.clust)
# rownames(output.stats.df) <- clust.assess
output <- rbind(output.stats.df, cluster.sizes)[ ,-1]
colnames(output) <- stats.names[2:k]
rownames(output) <- rows.all
is.num <- sapply(output, is.numeric)
output[is.num] <- lapply(output[is.num], round, 2)
output
}
ward_clust = hclust(gower_dist, method="ward.D2")
average_clust = hclust(gower_dist, method="average")
median_clust = hclust(gower_dist, method="median")
centroid_clust = hclust(gower_dist, method="centroid")

stats_ward = cstats.table(gower_dist, ward_clust, 10)
stats_average = cstats.table(gower_dist, average_clust, 10)
stats_median = cstats.table(gower_dist, median_clust, 10)
stats_centroid = cstats.table(gower_dist, centroid_clust, 10)

2.3.1 Ward

Tras obervar los gráficos de SS y el coeficiente de Silhoutte, el número de clusters elegidos es 6, porque tiene el mismo coeficiente de Silhoutte que con 4 y 5 clusters. Sin embargo, la suma de cuadrados intracluster es más pequeña.

El número de pisos en cada cluster es el siguiente:

## ward_groups
##   1   2   3   4   5   6 
## 654 223 249 488 498 109
El resumen estasístico del método de Ward es:
Test 1 Test 2 Test 3 Test 4 Test 5 Test 6 Test 7 Test 8 Test 9
cluster.number 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00
n 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00
within.cluster.ss 78.47 71.28 65.73 60.63 56.56 53.27 50.29 47.65 45.08
average.within 0.25 0.23 0.22 0.21 0.20 0.20 0.19 0.18 0.18
average.between 0.32 0.30 0.30 0.30 0.30 0.29 0.29 0.29 0.29
wb.ratio 0.78 0.77 0.73 0.71 0.68 0.67 0.65 0.63 0.61
dunn2 1.27 1.05 1.06 1.06 1.02 0.96 0.86 0.86 0.86
avg.silwidth 0.21 0.12 0.12 0.13 0.12 0.12 0.11 0.12 0.12
Cluster- 1 size 763.00 763.00 654.00 654.00 654.00 423.00 423.00 423.00 219.00
Cluster- 2 size 1458.00 960.00 960.00 223.00 223.00 223.00 223.00 223.00 223.00
Cluster- 3 size 0.00 498.00 498.00 737.00 249.00 249.00 249.00 249.00 204.00
Cluster- 4 size 0.00 0.00 109.00 498.00 488.00 488.00 488.00 294.00 249.00
Cluster- 5 size 0.00 0.00 0.00 109.00 498.00 231.00 231.00 231.00 294.00
Cluster- 6 size 0.00 0.00 0.00 0.00 109.00 498.00 295.00 295.00 231.00
Cluster- 7 size 0.00 0.00 0.00 0.00 0.00 109.00 109.00 109.00 295.00
Cluster- 8 size 0.00 0.00 0.00 0.00 0.00 0.00 203.00 203.00 109.00
Cluster- 9 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 194.00 203.00
Cluster- 10 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 194.00

2.3.2 Media

Tras obervar los gráficos de SS y el coeficiente de Silhoutte, el número de clusters elegidos es 4. A pesar de ello, es indiferente que el número de clusters sea 4,5 o 6, ya que este método forma un cluster con la mayoría de pisos (en torno a 2000) y el resto de clusters con menos de 200 pisos (e incluso menos de 50).

El número de pisos en cada cluster es el siguiente:

## average_groups
##    1    2    3    4 
## 2200    6    7    8
El resumen estadístico de este método es:
Test 1 Test 2 Test 3 Test 4 Test 5 Test 6 Test 7 Test 8 Test 9
cluster.number 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00
n 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00
within.cluster.ss 98.73 98.05 97.38 95.47 77.89 77.58 77.50 77.41 74.34
average.within 0.28 0.28 0.27 0.27 0.25 0.25 0.25 0.25 0.24
average.between 0.42 0.40 0.39 0.38 0.36 0.36 0.36 0.36 0.36
wb.ratio 0.66 0.68 0.70 0.71 0.68 0.68 0.68 0.68 0.67
dunn2 1.51 1.42 1.38 1.38 1.35 1.31 1.16 1.20 1.25
avg.silwidth 0.32 0.20 0.17 0.14 0.16 0.15 0.14 0.14 0.11
Cluster- 1 size 2215.00 2208.00 2200.00 2177.00 1872.00 1872.00 1872.00 1872.00 1872.00
Cluster- 2 size 6.00 6.00 6.00 23.00 305.00 300.00 300.00 300.00 189.00
Cluster- 3 size 0.00 7.00 7.00 6.00 23.00 23.00 23.00 23.00 23.00
Cluster- 4 size 0.00 0.00 8.00 7.00 6.00 6.00 5.00 5.00 111.00
Cluster- 5 size 0.00 0.00 0.00 8.00 7.00 7.00 7.00 7.00 5.00
Cluster- 6 size 0.00 0.00 0.00 0.00 8.00 5.00 5.00 3.00 7.00
Cluster- 7 size 0.00 0.00 0.00 0.00 0.00 8.00 8.00 2.00 3.00
Cluster- 8 size 0.00 0.00 0.00 0.00 0.00 0.00 1.00 8.00 2.00
Cluster- 9 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 8.00
Cluster- 10 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00

2.3.3 Centroide

Al igual que ha ocurrido con el método de la media, este método tampoco separa “correctamente” los clusters. Da igual escoger una k de 3,4 o 5 porque el primer cluster tiene prácticamente todos los pisos y el resto de clusters, 1, 2 o 3. Los gráficos del coeficiente de Silhoutte y de la SS se encuentran son:

El número de pisos en cada cluster es el siguiente:

## centroid_groups
##    1    2    3    4    5 
## 2217    1    1    1    1
El resumen estadístico del método del Centroide es:
Test 1 Test 2 Test 3 Test 4 Test 5 Test 6 Test 7 Test 8 Test 9
cluster.number 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00
n 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00
within.cluster.ss 99.25 98.98 98.95 98.84 98.74 98.51 97.90 97.19 97.05
average.within 0.28 0.28 0.28 0.28 0.28 0.28 0.28 0.27 0.27
average.between 0.46 0.44 0.44 0.43 0.41 0.41 0.41 0.42 0.42
wb.ratio 0.61 0.62 0.62 0.65 0.67 0.68 0.67 0.66 0.66
dunn2 1.64 1.58 0.93 0.93 0.93 0.93 0.93 0.87 0.94
avg.silwidth 0.35 0.25 0.22 0.14 0.02 0.00 -0.01 -0.01 -0.02
Cluster- 1 size 2220.00 2218.00 2218.00 2217.00 2216.00 2214.00 2209.00 2203.00 2203.00
Cluster- 2 size 1.00 1.00 1.00 1.00 1.00 1.00 5.00 5.00 5.00
Cluster- 3 size 0.00 2.00 1.00 1.00 1.00 1.00 1.00 6.00 3.00
Cluster- 4 size 0.00 0.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00
Cluster- 5 size 0.00 0.00 0.00 1.00 1.00 1.00 1.00 1.00 3.00
Cluster- 6 size 0.00 0.00 0.00 0.00 1.00 2.00 1.00 1.00 1.00
Cluster- 7 size 0.00 0.00 0.00 0.00 0.00 1.00 2.00 1.00 1.00
Cluster- 8 size 0.00 0.00 0.00 0.00 0.00 0.00 1.00 2.00 1.00
Cluster- 9 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 2.00
Cluster- 10 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00

2.3.4 Mediana

Del mismo modo que con los dos métodos anteriores ocurre con el método de la mediana. Además, como se puede observar en el gráfico del coeficiente de Silhoutte, sólo con k=2 o k=3 es positivo.

Aun con este número de clusters, vemos cómo el patrón se repite: el primer cluster con la mayoría de pisos y el resto con 1 o 5 pisos.

## median_groups
##    1    2    3 
## 2219    1    1
El resumen estadístico de este método es:
Test 1 Test 2 Test 3 Test 4 Test 5 Test 6 Test 7 Test 8 Test 9
cluster.number 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00
n 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00 2221.00
within.cluster.ss 99.33 99.20 99.11 98.36 98.28 98.18 98.04 97.82 97.76
average.within 0.28 0.28 0.28 0.28 0.28 0.28 0.28 0.28 0.28
average.between 0.37 0.38 0.38 0.43 0.43 0.43 0.43 0.42 0.42
wb.ratio 0.75 0.72 0.74 0.64 0.64 0.65 0.65 0.66 0.66
dunn2 1.33 1.00 1.00 0.90 1.00 1.00 1.00 1.00 1.00
avg.silwidth 0.22 0.13 0.04 0.03 0.00 -0.08 -0.08 -0.09 -0.09
Cluster- 1 size 2220.00 2219.00 2218.00 2213.00 2213.00 2212.00 2211.00 2209.00 2209.00
Cluster- 2 size 1.00 1.00 1.00 5.00 1.00 1.00 1.00 1.00 1.00
Cluster- 3 size 0.00 1.00 1.00 1.00 4.00 4.00 4.00 4.00 3.00
Cluster- 4 size 0.00 0.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00
Cluster- 5 size 0.00 0.00 0.00 1.00 1.00 1.00 1.00 1.00 1.00
Cluster- 6 size 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00 1.00
Cluster- 7 size 0.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00
Cluster- 8 size 0.00 0.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00
Cluster- 9 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00 1.00
Cluster- 10 size 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00

2.4 Métodos de partición: K-medoides

El método de K-medoides, en comparación con el método de K-medias, es mucho más robusto, puesto que, los medoides son mejores representantes de los clusters que los centroides.

dataCluster[which(gower_mat == min(gower_mat[gower_mat != min(gower_mat)]), arr.ind = TRUE)[1, ], ]
##     baños jardin ascensor piscina terraza habitaciones a_reformar tipo_vendedor
## 515     2      0        1       0       0            3          0             2
## 51      2      0        1       0       0            3          0             2
##     armarios.empotrados acceso.adaptado aire.acondicionado balcon trastero
## 515                   1               0                  1      1        0
## 51                    1               0                  1      1        0
##     garaje.incluido calefaccion planta vistas
## 515               0           1      7      1
## 51                0           1      8      1
sil_width = c(NA)
for(i in 2:10){  
  pam_fit = pam(gower_dist, diss = TRUE, k = i)  
  sil_width[i] = pam_fit$silinfo$avg.width  
}

Como podemos observar en el gráfico del coeficiente de Silhoutte, el número de clusters elegido es 6, porque tiene un coeficiente más alto que con k=5 y k=7

k = 6
pam_fit = pam(gower_dist, diss = TRUE, k)

2.5 Selección del método de clustering

Tras ver todos los métodos, descartamos el método de la media, de la mediana y del centroide. Ahora, nos toca seleccionar entre el método de Ward y K-Medoides:

El método final seleccionado es el método K-Medoides porque tiene un mayor coeficiente de silhoutte medio. Además, tiene menas observaciones mal clasificadas (negativos).

clust = pam_fit$clustering
dist = vend$distrito
data = data.frame(clust, dist)

tsne_object <- Rtsne(gower_dist, is_distance = TRUE, dims = 3)
tsne_df <- tsne_object$Y %>%
  data.frame() %>%
  setNames(c("X", "Y", "Z")) %>%
  mutate(cluster = factor(pam_fit$clustering))

plot_ly(x=tsne_df$X, y=tsne_df$Y, z=tsne_df$Z, size = I(15), type="scatter3d", mode="markers", color=tsne_df$cluster)
plot_ly(x=tsne_df$X, y=tsne_df$Y, size = I(15), type="scatter", mode="markers", color=tsne_df$cluster)

Por último, haremos un estudio más detallado para ver si hay clusters en los que predomina algún distrito.

pam_results = dataCluster %>%
  mutate(cluster = pam_fit$clustering) %>%
  group_by(cluster) %>%
  do(the_summary = summary(.))
1 2 3 4 5 6
algirós 23 5 7 15 6 3
benicalap 8 16 10 23 10 34
benimaclet 7 0 1 0 5 9
camins al grau 22 11 13 18 11 16
campanar 17 16 30 15 9 6
ciutat vella 68 40 17 28 51 22
el pla del real 11 24 25 6 14 1
extramurs 36 31 14 31 38 14
jesús 31 8 16 31 6 28
l’eixample 68 33 27 32 41 14
l’olivereta 21 4 6 24 11 34
la saïdia 20 5 10 36 14 26
patraix 47 11 8 50 23 18
poblats marítims 54 23 15 52 46 89
pobles de l’oest 3 2 1 4 4 6
pobles del nord 1 0 0 2 0 1
pobles del sud 8 11 6 19 3 17
quatre carreres 32 27 20 38 21 29
rascanya 30 13 11 44 5 44

2.6 Cluster 1

pam_results$the_summary[[1]]
##      baños      jardin  ascensor piscina terraza  habitaciones   a_reformar
##  Min.   :1.00   0:495   0: 73    0:498   0:487   Min.   :1.000   0:459     
##  1st Qu.:1.00   1: 12   1:434    1:  9   1: 20   1st Qu.:3.000   1: 48     
##  Median :2.00                                    Median :3.000             
##  Mean   :1.74                                    Mean   :3.162             
##  3rd Qu.:2.00                                    3rd Qu.:4.000             
##  Max.   :8.00                                    Max.   :8.000             
##  tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon 
##  1: 25         0:105               0:411           0:124              0:  0  
##  2:482         1:402               1: 96           1:383              1:507  
##                                                                              
##                                                                              
##                                                                              
##                                                                              
##  trastero garaje.incluido calefaccion     planta       vistas     cluster 
##  0:436    0:432           0:164       Min.   : 0.000   0: 17   Min.   :1  
##  1: 71    1: 75           1:343       1st Qu.: 2.000   1:490   1st Qu.:1  
##                                       Median : 3.000           Median :1  
##                                       Mean   : 3.639           Mean   :1  
##                                       3rd Qu.: 5.000           3rd Qu.:1  
##                                       Max.   :14.000           Max.   :1
clust1 = data[data$clust==1, ]
ggplot(data = clust1, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 1")

num1 = table(clust1$dist)
perc1 = 100*num1/sum(num1)
kable(cbind(num1, perc1))
num1 perc1
algirós 23 4.5364892
benicalap 8 1.5779093
benimaclet 7 1.3806706
camins al grau 22 4.3392505
campanar 17 3.3530572
ciutat vella 68 13.4122288
el pla del real 11 2.1696252
extramurs 36 7.1005917
jesús 31 6.1143984
l’eixample 68 13.4122288
l’olivereta 21 4.1420118
la saïdia 20 3.9447732
patraix 47 9.2702170
poblats marítims 54 10.6508876
pobles de l’oest 3 0.5917160
pobles del nord 1 0.1972387
pobles del sud 8 1.5779093
quatre carreres 32 6.3116371
rascanya 30 5.9171598

El cluster 1 está formado por 556 pisos con una media de 1,75 baños y 3,165 habitaciones y con ascensor (85,43%), armarios empotrados (81,11%), aire acondicionado (85,35%), balcón (100%) y sin jardín (97,30%), ni piscina (97,66%), ni terraza (88,31%), ni adaptados a personas con movilidad reducida (82,55%), ni garaje incluido (76,43%), ni trastero (84,71%). Generalmente estos pisos tienen una altura “mediana” (con una media de 3.892) y son exteriores (95,6%).

Como se puede observar, el peso del balcón es muy grande. Los pisos que tienen estas características (incluido balcón) se encuentran desperdigados por toda Valencia (Ciutat Vella en un 13,31%, L’Eixample en un 12,41% y Poblats Marítims en un 10,07%).

2.7 Cluster 2

pam_results$the_summary[[2]]
##      baños       jardin  ascensor piscina terraza  habitaciones   a_reformar
##  Min.   :1.000   0:245   0: 22    0:236   0:  0   Min.   :1.000   0:263     
##  1st Qu.:2.000   1: 35   1:258    1: 44   1:280   1st Qu.:2.000   1: 17     
##  Median :2.000                                    Median :3.000             
##  Mean   :2.057                                    Mean   :3.321             
##  3rd Qu.:2.000                                    3rd Qu.:4.000             
##  Max.   :5.000                                    Max.   :8.000             
##  tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon 
##  1: 23         0: 58               0:232           0: 61              0:259  
##  2:257         1:222               1: 48           1:219              1: 21  
##                                                                              
##                                                                              
##                                                                              
##                                                                              
##  trastero garaje.incluido calefaccion     planta       vistas     cluster 
##  0:220    0:206           0: 78       Min.   : 0.000   0: 12   Min.   :2  
##  1: 60    1: 74           1:202       1st Qu.: 1.000   1:268   1st Qu.:2  
##                                       Median : 2.000           Median :2  
##                                       Mean   : 3.564           Mean   :2  
##                                       3rd Qu.: 5.000           3rd Qu.:2  
##                                       Max.   :18.000           Max.   :2
clust2 = data[data$clust==2, ]
ggplot(data = clust2, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 2")

num2 = table(clust2$dist)
perc2 = 100*num2/sum(num2)
kable(cbind(num2, perc2))
num2 perc2
algirós 5 1.7857143
benicalap 16 5.7142857
benimaclet 0 0.0000000
camins al grau 11 3.9285714
campanar 16 5.7142857
ciutat vella 40 14.2857143
el pla del real 24 8.5714286
extramurs 31 11.0714286
jesús 8 2.8571429
l’eixample 33 11.7857143
l’olivereta 4 1.4285714
la saïdia 5 1.7857143
patraix 11 3.9285714
poblats marítims 23 8.2142857
pobles de l’oest 2 0.7142857
pobles del nord 0 0.0000000
pobles del sud 11 3.9285714
quatre carreres 27 9.6428571
rascanya 13 4.6428571

El cluster 2 está formado por 480 pisos con una media de 1,85 baños y 3 habitaciones y con ascensor (90,83%), armarios empotrados (80,41%), aire acondicionado (88,54%), calefacción (82,29%) y sin jardín (97,70%), ni piscina (97,29%), ni terraza (68,12%), ni adaptados a personas con movilidad reducida (75,62%), ni balcón (0%), ni trastero (86,87%). Generalmente estos pisos tienen una altura “mediana” (con una media de 3.56) y son exteriores (93,96%).

Como se puede observar de nuevo, el peso del balcón es muy grande. Los pisos que tienen estas características (sin balcón) se encuentran desperdigados por toda Valencia (Ciutat Vella en un 15,42%, L’Eixample en un 14,38%, Extramurs en un 11,88% y Poblats Marítims en un 12,50%).

2.8 Cluster 3

pam_results$the_summary[[3]]
##      baños       jardin  ascensor piscina terraza  habitaciones   a_reformar
##  Min.   :1.000   0:185   0:  2    0:191   0: 61   Min.   :1.000   0:222     
##  1st Qu.:2.000   1: 52   1:235    1: 46   1:176   1st Qu.:3.000   1: 15     
##  Median :2.000                                    Median :3.000             
##  Mean   :2.148                                    Mean   :3.422             
##  3rd Qu.:2.000                                    3rd Qu.:4.000             
##  Max.   :6.000                                    Max.   :7.000             
##  tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon 
##  1: 23         0: 33               0: 44           0: 48              0: 54  
##  2:214         1:204               1:193           1:189              1:183  
##                                                                              
##                                                                              
##                                                                              
##                                                                              
##  trastero garaje.incluido calefaccion     planta       vistas     cluster 
##  0:153    0: 59           0: 51       Min.   : 0.000   0:  6   Min.   :3  
##  1: 84    1:178           1:186       1st Qu.: 2.000   1:231   1st Qu.:3  
##                                       Median : 4.000           Median :3  
##                                       Mean   : 4.679           Mean   :3  
##                                       3rd Qu.: 7.000           3rd Qu.:3  
##                                       Max.   :18.000           Max.   :3
clust3 = data[data$clust==3, ]
ggplot(data = clust3, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 3")

num3 = table(clust3$dist)
perc3 = 100*num3/sum(num3)
kable(cbind(num3, perc3))
num3 perc3
algirós 7 2.9535865
benicalap 10 4.2194093
benimaclet 1 0.4219409
camins al grau 13 5.4852321
campanar 30 12.6582278
ciutat vella 17 7.1729958
el pla del real 25 10.5485232
extramurs 14 5.9071730
jesús 16 6.7510549
l’eixample 27 11.3924051
l’olivereta 6 2.5316456
la saïdia 10 4.2194093
patraix 8 3.3755274
poblats marítims 15 6.3291139
pobles de l’oest 1 0.4219409
pobles del nord 0 0.0000000
pobles del sud 6 2.5316456
quatre carreres 20 8.4388186
rascanya 11 4.6413502

El cluster 3 está formado por 234 pisos con una media de 1,885 baños y 3,462 habitaciones y con ascensor (89,32%), terraza (75,21%), armarios empotrados (77,35%), adaptados a personas con movilidad reducida (85,47%), balcón (78,63%), calefacción (78,21%) y sin jardín (97,86%), ni piscina (97,44%), ni aire acondicionado (65,81%), ni trastero (83,76%), ni garaje (75,21%). Generalmente los pisos tienen una altura “mediana” (con una media de 3,98) y son exteriores (95,30%).

En este cluster, se encuentran pisos adecuados para personas con movilidad reducida, ya que además de estar adaptados, la mayoría cuenta con ascensor. Estos pisos están localizados, de nuevo, por toda la ciudad (Ciutat Vella en un 11,54%, L’Eixample en un 11,97% y Poblats Marítims en un 10,68%).

2.9 Cluster 4

pam_results$the_summary[[4]]
##      baños     jardin  ascensor piscina terraza  habitaciones   a_reformar
##  Min.   :1.0   0:446   0:  0    0:437   0:370   Min.   :1.000   0:393     
##  1st Qu.:1.0   1: 22   1:468    1: 31   1: 98   1st Qu.:2.000   1: 75     
##  Median :1.0                                    Median :3.000             
##  Mean   :1.5                                    Mean   :3.113             
##  3rd Qu.:2.0                                    3rd Qu.:4.000             
##  Max.   :6.0                                    Max.   :9.000             
##  tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon 
##  1: 23         0:387               0:400           0:402              0:340  
##  2:445         1: 81               1: 68           1: 66              1:128  
##                                                                              
##                                                                              
##                                                                              
##                                                                              
##  trastero garaje.incluido calefaccion     planta       vistas     cluster 
##  0:422    0:410           0:384       Min.   : 0.000   0: 37   Min.   :4  
##  1: 46    1: 58           1: 84       1st Qu.: 2.000   1:431   1st Qu.:4  
##                                       Median : 3.000           Median :4  
##                                       Mean   : 3.551           Mean   :4  
##                                       3rd Qu.: 5.000           3rd Qu.:4  
##                                       Max.   :14.000           Max.   :4
clust4 = data[data$clust==4, ]
ggplot(data = clust4, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 4")

num4 = table(clust4$dist)
perc4 = 100*num4/sum(num4)
kable(cbind(num4, perc4))
num4 perc4
algirós 15 3.2051282
benicalap 23 4.9145299
benimaclet 0 0.0000000
camins al grau 18 3.8461538
campanar 15 3.2051282
ciutat vella 28 5.9829060
el pla del real 6 1.2820513
extramurs 31 6.6239316
jesús 31 6.6239316
l’eixample 32 6.8376068
l’olivereta 24 5.1282051
la saïdia 36 7.6923077
patraix 50 10.6837607
poblats marítims 52 11.1111111
pobles de l’oest 4 0.8547009
pobles del nord 2 0.4273504
pobles del sud 19 4.0598291
quatre carreres 38 8.1196581
rascanya 44 9.4017094

El cluster 4 está formado por 495 pisos con una media de 1,628 baños y 3,17 habitaciones y con únicamente ascensor (100%). En su mayoría, ninguno dispone de jardín (95,96%), ni piscina (94,34%), ni terraza (76,97%), ni armarios empotrados (83,03%), ni aire acondicionado (84,24%), ni balcón (74,34%), ni trastero (90,71%), ni garaje incluido (85,05%), ni calefacción (95,05%). Generalmente los pisos tienen una altura “mediana” (con una media de 3,36) y son exteriores (94,75%).

Como se puede observar, los pisos de este cluster, aunque tienen ascensor, parece que son “básicos”. Probablemente, sean los pisos más baratos de la ciudad. Estas observaciones se encuentran por toda Valencia.

2.10 Cluster 5

pam_results$the_summary[[5]]
##      baños       jardin  ascensor piscina terraza  habitaciones   a_reformar
##  Min.   :1.000   0:302   0: 28    0:300   0:318   Min.   :1.000   0:292     
##  1st Qu.:1.000   1: 16   1:290    1: 18   1:  0   1st Qu.:2.000   1: 26     
##  Median :2.000                                    Median :3.000             
##  Mean   :1.748                                    Mean   :2.928             
##  3rd Qu.:2.000                                    3rd Qu.:3.000             
##  Max.   :5.000                                    Max.   :6.000             
##  tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon 
##  1: 17         0: 60               0:229           0: 50              0:318  
##  2:301         1:258               1: 89           1:268              1:  0  
##                                                                              
##                                                                              
##                                                                              
##                                                                              
##  trastero garaje.incluido calefaccion     planta       vistas     cluster 
##  0:275    0:250           0: 55       Min.   : 0.000   0: 21   Min.   :5  
##  1: 43    1: 68           1:263       1st Qu.: 2.000   1:297   1st Qu.:5  
##                                       Median : 3.000           Median :5  
##                                       Mean   : 3.717           Mean   :5  
##                                       3rd Qu.: 5.000           3rd Qu.:5  
##                                       Max.   :14.000           Max.   :5
clust5 = data[data$clust==5, ]
ggplot(data = clust5, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 5")

num5 = table(clust5$dist)
perc5 = 100*num5/sum(num5)
kable(cbind(num5, perc5))
num5 perc5
algirós 6 1.8867925
benicalap 10 3.1446541
benimaclet 5 1.5723270
camins al grau 11 3.4591195
campanar 9 2.8301887
ciutat vella 51 16.0377358
el pla del real 14 4.4025157
extramurs 38 11.9496855
jesús 6 1.8867925
l’eixample 41 12.8930818
l’olivereta 11 3.4591195
la saïdia 14 4.4025157
patraix 23 7.2327044
poblats marítims 46 14.4654088
pobles de l’oest 4 1.2578616
pobles del nord 0 0.0000000
pobles del sud 3 0.9433962
quatre carreres 21 6.6037736
rascanya 5 1.5723270

El cluster 5 está formado por 444 pisos con una media de 1,196 baños y 2,721 habitaciones y sin ningún equipamiento adicional. Generalmente, los pisos tienen una altura “baja” (con una media de 2,655) y son exteriores (95,49%).

Como se puede observar, los pisos de este cluster se encuentran principalmente en Poblats Marítims (22,07%). Probablemente, sean los pisos más baratos de la ciudad.

2.11 Cluster 6

pam_results$the_summary[[6]]
##      baños       jardin  ascensor piscina terraza  habitaciones   a_reformar
##  Min.   :1.000   0:407   0:411    0:411   0:350   Min.   :1.000   0:347     
##  1st Qu.:1.000   1:  4   1:  0    1:  0   1: 61   1st Qu.:2.000   1: 64     
##  Median :1.000                                    Median :3.000             
##  Mean   :1.136                                    Mean   :2.669             
##  3rd Qu.:1.000                                    3rd Qu.:3.000             
##  Max.   :2.000                                    Max.   :6.000             
##  tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon 
##  1: 10         0:353               0:382           0:353              0:311  
##  2:401         1: 58               1: 29           1: 58              1:100  
##                                                                              
##                                                                              
##                                                                              
##                                                                              
##  trastero garaje.incluido calefaccion     planta       vistas     cluster 
##  0:397    0:409           0:271       Min.   : 0.000   0: 21   Min.   :6  
##  1: 14    1:  2           1:140       1st Qu.: 1.000   1:390   1st Qu.:6  
##                                       Median : 3.000           Median :6  
##                                       Mean   : 2.893           Mean   :6  
##                                       3rd Qu.: 4.000           3rd Qu.:6  
##                                       Max.   :17.000           Max.   :6
clust6 = data[data$clust==6, ]
ggplot(data = clust6, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 6")

num6 = table(clust6$dist)
perc6 = 100*num6/sum(num6)
kable(cbind(num6, perc6))
num6 perc6
algirós 3 0.729927
benicalap 34 8.272506
benimaclet 9 2.189781
camins al grau 16 3.892944
campanar 6 1.459854
ciutat vella 22 5.352798
el pla del real 1 0.243309
extramurs 14 3.406326
jesús 28 6.812652
l’eixample 14 3.406326
l’olivereta 34 8.272506
la saïdia 26 6.326034
patraix 18 4.379562
poblats marítims 89 21.654501
pobles de l’oest 6 1.459854
pobles del nord 1 0.243309
pobles del sud 17 4.136253
quatre carreres 29 7.055961
rascanya 44 10.705596

El cluster 6 está formado por 153 pisos con una media de 2,464 baños y 3,431 habitaciones, con jardín (69,28%), ascensor (84,31%), piscina (73,20%), terraza (85,62%), armarios empotrados (86,93%), aire acondicionado (85,62%), trastero (69,93%), garaje incluido (85,62%) y calefacción (71,24%) y sin balcón (74,51%).

Como se puede observar, los pisos de este clusters son los que más “equipamiento” tienen. Se caracterizan principalmente por tener piscina y encontrarse en Campanar (25,49%). Estos pisos tienen una altura “mediana-alta” (con una media de 4,549) y son en su totalidad exteriores (99,34%).